////////////////////////////////////////////////////////////////////////////////
// Filename: beziercurve.cpp
////////////////////////////////////////////////////////////////////////////////
#include "beziercurve.h"
#include <d3dx10math.h>

Beziercurve::Beziercurve()
{
	
}




Beziercurve::~Beziercurve()
{
}


bool Beziercurve::initialize(int pointcount, int steps)
{
	numElements = 0;
	listsize = pointcount;
	beziersteps = steps;
	currentstep = 0;
	points = new D3DXVECTOR3[listsize];
	for(int i=0;i<listsize;i++)
		points[i] = D3DXVECTOR3(0.0f,0.0f,0.0f);
	return true;
}
bool Beziercurve::addPoint(D3DXVECTOR3 point)
{
	if(numElements<listsize) {
		points[numElements] = point;
		numElements++;
		return true;
	} else {
		return false;
	}
}
void Beziercurve::rotateY(float radians) {
	for(int i = 0; i<numElements;i++) {
		float z = points[i].z*cosf(radians) - points[i].x*sinf(radians);
		float x = points[i].z*sinf(radians) + points[i].x*cosf(radians);
		points[i].x = x;
		points[i].z = z;
	}
}
void Beziercurve::rotateX(float radians) {
	for(int i = 0; i<numElements;i++) {
		float y = points[i].y*cosf(radians) - points[i].z*sinf(radians);
		float z = points[i].y*sinf(radians) + points[i].z*cosf(radians);
		points[i].z = z;
		points[i].y = y;
	}
}
void Beziercurve::rotateZ(float radians) {
	for(int i = 0; i<numElements;i++) {
		float x = points[i].x*cosf(radians) - points[i].y*sinf(radians);
		float y = points[i].x*sinf(radians) + points[i].y*cosf(radians);
		points[i].x = x;
		points[i].y = y;
	}
}
D3DXVECTOR3 Beziercurve::getPosition(float t) {
	D3DXVECTOR3 result;
	result.x = 0;
	result.y = 0;
	result.z = 0;
	float temp1 = 1;
	float temp2 = 1;
	for(int i = 0; i < numElements; i++) {
		temp1 = 1;
		for(int j = 0; j<numElements-i-1;j++) {
			temp1 = temp1*(1-t);
		}
		temp2 = 1;
		for(int j = 0; j<i;j++) {
			temp2 = temp2*t;
		}
		result += bin(numElements-1, i)*temp1*temp2*points[i];
	}
	return result;
}
float Beziercurve::bin (long int n, long int k)
{
   long int i;
   float binomialkoeffizient = 1;

   if (n <  0 || n > 20 || k < 0 || k > n) return (-1);

   if (k == 0 || k == n) return (binomialkoeffizient);

   for (i = 1; i <= k; i++)
      binomialkoeffizient = binomialkoeffizient * (n - i + 1) / i;
   return (binomialkoeffizient);
}
D3DXVECTOR3 Beziercurve::getNextPosition() {
	currentstep = currentstep +  (1.0f / (float)beziersteps);
	if(currentstep>1)
		currentstep = 0;
	return getPosition(currentstep);
}